package cn.com.bluemoon.daps.system.utils;

import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.com.bluemoon.daps.common.exception.DapThrowException;
import cn.com.bluemoon.daps.common.toolkit.DbType;
import cn.com.bluemoon.daps.common.toolkit.DbTypeHelper;
import cn.com.bluemoon.daps.system.entity.DapSystemDatasourceEnvironment;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Base64;

public class ConnectUtils {

    /**
     * 数据源测试连接
     */
    public static String connectTest(DatabaseType databaseType, DapSystemDatasourceEnvironment environment) {
        String url = formatUrl(DbTypeHelper.getDbType(databaseType), environment.getHost(), environment.getPort(), environment.getDatabaseName());
        //获取连接
        try {
            String driverClassName = driverClassName(DbTypeHelper.getDbType(databaseType).name());
            Class.forName(driverClassName);
            String databaseProductVersion;
            try (Connection connection = DriverManager.getConnection(url, environment.getUsername(), environment.getPassword())) {
                DatabaseMetaData metaData = connection.getMetaData();
                databaseProductVersion = metaData.getDatabaseProductVersion();
            }
            return databaseProductVersion;
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
            throw new DapThrowException("测试连接失败，"+ExceptionUtils.getMessage(e));
        }
    }

    public static String formatUrl(DbType dbType, String host, Integer port, String dbName) {
        if (dbType != null && host != null && port != null) {
            String name;
            if (DbType.hive.equals(dbType)) {
                name = "hive2";
            } else if (DbType.mysql.equals(dbType)) {
                name = "mysql";
                return String.format("jdbc:%s://%s:%d/%s?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai", name, host, port, dbName);
            } else if (DbType.postgresql.equals(dbType)) {
                name = "postgresql";
                return String.format("jdbc:%s://%s:%d/%s?useUnicode=true&characterEncoding=utf8", name, host, port, dbName);
            } else if (DbType.sqlserver.equals(dbType)) {
                name = "sqlserver";
                return String.format("jdbc:%s://%s:%d/%s?useUnicode=true&characterEncoding=utf8", name, host, port, dbName);
            } else if (DbType.sapdb.equals(dbType)) {
                name = "sap";
            } else if (DbType.impala.equals(dbType)) {
                name = "impala";
            } else if (DbType.phoenix.equals(dbType)) {
                name = "phoenix";
                return String.format("jdbc:%s:%s:%d", name, host, port);
            } else {
                throw new DapThrowException("jdbc取数暂不支持数据库类型：" + dbType);
            }
            return String.format("jdbc:%s://%s:%d/%s", name, host, port, dbName);
        }
        return null;
    }

    public static String driverClassName(String dbType) {
        if (dbType != null) {
            switch (dbType.toLowerCase()) {
                case "mysql":
                    return "com.mysql.jdbc.Driver";
                case "postgresql":
                    return "org.postgresql.Driver";
                case "sqlserver":
                    return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
                case "sap":
                case "sapdb":
                case "hana":
                    return "com.sap.db.jdbc.Driver";
                case "hive":
                    return "org.apache.hive.jdbc.HiveDriver";
                case "impala":
                    return "com.cloudera.impala.jdbc41.Driver";
                case "phoenix":
                    return "org.apache.phoenix.jdbc.PhoenixDriver";
                default:
                    throw new DapThrowException("暂不支持该数据库，dbType=" + dbType);
            }
        }
        return null;
    }


    /**
     * md5解密
     */
    public static ResultBean<String> decoderBase(String string) {

        try {
            String password = new String(Base64.getDecoder().decode(string), "UTF-8");
            return ResultBean.ok(password);
        } catch (UnsupportedEncodingException e) {
            return ResultBean.error(e.getMessage());
        }
    }
}
